--------------------------------------------------------------------------------------------------------------------------------------- 
--版权声明：本demo集源于上海合宙官方技术团队的DEMO（MIT），并参考了合宙开源社区的众多大佬无私分享的代码，包括但不限于 稀饭放姜、Wendal、晨旭等
-- 目前参考到的开源项目有： iRTU（MIT)、LuatOS(MIT)
-- 欲获取更多luat 代码请访问 doc.openluat.com
-- 如果您觉得本demo集包含了未经由您授权的代码，请联系 64034373@qq.com 
---------------------------------------------------------------------------------------------------------------------------------------

-- @模块功能：串口命令模块
-- @author miuser
-- @module midemo.com
-- @license MIT
-- @copyright miuser@luat
-- @release 2020-08-28
--------------------------------------------------------------------------
-- @使用方法
-- @外部串口发送指令形如 COMMAND,PARA1,PARA2,PARA3.... 参数中不可以有逗号
-- @串口收到指令后通过sys.publish(COMMAND,PARA1,PARA2,PARA3....)的形式转化为系统消息，发布出去。
-- @当接收其他模块发送的任何主题为“COM”的消息,则转发到串口出来。比如消息为 {"COM","AA","1"},则串口将对外发送AA,1
-- @消息收发均采用utf8编码，与lua文件系统相同
-------------------------------------------- 配置串口 ---------------------
require "common"

module(...,package.seeall)


-- 串口ID,串口读缓冲区
local sendQueue= {}
-- 串口超时，串口准备好后发布的消息
-- 这个参数要根据波特率调整，波特率如果比较低，相应的timeout要延长，单位是ms
-- 一般来说115200bps建议用25, 9600bps建议调到100
local uartimeout= 25
--保持系统处于唤醒状态，不会休眠
pm.wake("com")
-- 初始化所有被指派为控制台的串口
for i=1,#bs.COM_UART_IDs do
    uart.setup(bs.COM_UART_IDs[i], 115200, 8, uart.PAR_NONE, uart.STOP_1, nil, 1)

    uart.on(bs.COM_UART_IDs[i], "receive", function(uid)
        table.insert(sendQueue, uart.read(uid, 8192))
        sys.timerStart(sys.publish, uartimeout, "COMRSV")
    end)
end

-- 1 向串口发送收到的字符串加上->OK，并回送到串口
-- 2 将串口收到的消息转发成luatask系统消息
sys.subscribe("COMRSV", function()
    local str = table.concat(sendQueue)
    -- 串口的数据读完后清空缓冲区
    local splitlist = {}
    string.gsub(str, '[^,]+', function(w) table.insert(splitlist, w) end)
    local count=table.getn(splitlist)
    --sys.publish("UARTIN",str)
    for i=1,#splitlist do 
        splitlist[i]=common.gb2312ToUtf8(splitlist[i])
        splitlist[i]=bs.PIN_MAP(splitlist[i])
    end 
    sys.publish(unpack(splitlist))
    sendQueue = {}
    log.info("uart read:", str)
    sys.publish("DISPLAY",str)
    sys.publish("NET_RAW_MONI",str)
    write(str.."->OK".."\n\r")
end)

-- 向所有串口发送字符串
function write(str)
    for i=1,#bs.COM_UART_IDs do
        uart.write(bs.COM_UART_IDs[i], str)
    end
end

--从系统消息接收主题为“COM”的消息，并转发到串口
local function uartrsv(msg)
    for i=1,#bs.COM_UART_IDs do
        uart.write(bs.COM_UART_IDs[i], common.utf8ToGb2312(msg))
    end
end
sys.subscribe("COM", uartrsv)